/* eslint-disable no-nested-ternary */
/* eslint-disable array-callback-return */
/**
 * Ant Design Pro v4 use `@ant-design/pro-layout` to handle Layout.
 * You can view component api by:
 * https://github.com/ant-design/ant-design-pro-layout
 */
import ProLayout, {
  MenuDataItem,
  BasicLayoutProps as ProLayoutProps,
  Settings,
} from '@ant-design/pro-layout';
import React, { useEffect, useCallback } from 'react';
import { Link, useIntl, connect, Dispatch, history } from 'umi';
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
import { Result, Button, Menu, Breadcrumb, Layout } from 'antd';
import Authorized from '@/utils/Authorized';
import RightContent from '@/components/GlobalHeader/RightContent';
import { ConnectState } from '@/models/connect';
import { getAuthorityFromRouter } from '@/utils/utils';
import logo from '../assets/logo.svg';

const { Sider } = Layout;

const noMatch = (
  <Result
    status={403}
    title="403"
    subTitle="Sorry, you are not authorized to access this page."
    extra={
      <Button type="primary">
        <Link to="/user/login">Go Login</Link>
      </Button>
    }
  />
);

const { SubMenu } = Menu;

export interface BasicLayoutProps extends ProLayoutProps {
  breadcrumbNameMap: {
    [path: string]: MenuDataItem;
  };
  route: any;
  settings: Settings;
  dispatch: Dispatch;
}
export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & {
  breadcrumbNameMap: {
    [path: string]: MenuDataItem;
  };
};
/**
 * use Authorized check all menu item
 */

const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>
  menuList.map((item) => {
    const localItem = {
      ...item,
      children: item.children ? menuDataRender(item.children) : undefined,
    };
    return Authorized.check(item.authority, localItem, null) as MenuDataItem;
  });

const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
  const {
    dispatch,
    children,
    settings,
    location = {
      pathname: '/',
    },
    collapsed,
  } = props;

  const routeChildren = props.route.children.filter((item: any) => item.name);
  const { pathname } = location;
  const curname: any = pathname?.split('/')[1];
  let childrens: any[] = [];
  routeChildren.map((item: any) => {
    if (item.name === curname && item.routes) {
      childrens = item.routes;
    }
  });

  /**
   * constructor
   */

  useEffect(() => {
    if (dispatch) {
      dispatch({
        type: 'user/fetchCurrent',
      });
    }
  }, []);
  /**
   * init variables
   */

  const handleMenuCollapse = (payload: boolean): void => {
    if (dispatch) {
      dispatch({
        type: 'global/changeLayoutCollapsed',
        payload,
      });
    }
  }; // get children authority

  const authorized = getAuthorityFromRouter(props.route.routes, location.pathname || '/') || {
    authority: undefined,
  };

  const { formatMessage } = useIntl();

  const renderTopMenu = useCallback(() => {
    return routeChildren.map((item: any) => (
      // @ts-ignore
      <Menu.Item
        key={item.path}
        className={`${
          location.pathname?.indexOf(item.path) > -1
            ? 'ant-menu-item-active ant-menu-item-selected'
            : ''
        }`}
      >
        <Link to={item.redirect ? item.redirect : item.path}>
          {formatMessage({ id: `menu.${item.name}` })}
        </Link>
      </Menu.Item>
    ));
  }, [props]);

  const customMenuDataRender = (routes: any, name: string) =>
    // eslint-disable-next-line no-nested-ternary
    routes.map((item: any) => {
      if (item.path && !item.redirect && !item.hideInMenu) {
        if (item.routes) {
          return (
            <SubMenu
              title={
                <>
                  <span>{formatMessage({ id: `menu.${name}.${item.name}` })}</span>
                </>
              }
              key={name === '' ? item.path.split('/')[1] : item.path}
            >
              {customMenuDataRender(item.routes, `${name}.${item.name}`)}
            </SubMenu>
          );
        }
        return (
          // @ts-ignore
          <Menu.Item
            key={item.path}
            className={`${
              location.pathname?.indexOf(item.path) > -1
                ? 'ant-menu-item-active ant-menu-item-selected'
                : ''
            }`}
            icon={<>{item.icon && <span className="iconfont anticon">{item.icon}</span>}</>}
          >
            <Link to={{ pathname: item.path, state: { code: item.code } }}>
              {formatMessage({ id: `menu.${name}.${item.name}` })}
            </Link>
          </Menu.Item>
        );
      }
      return null;
    });

  const renderSideMenu = useCallback(() => {
    return childrens.length > 0 ? customMenuDataRender(childrens, curname) : null;
  }, [props, location]);

  const urlToList = (url: any) => {
    if (!url || url === '/') {
      return ['/'];
    }

    const urlList = url.split('/').filter((i: any) => {
      return i;
    });
    return urlList.map((urlItem: any, index: number) => {
      return '/'.concat(urlList.slice(0, index + 1).join('/'));
    });
  };

  return (
    <ProLayout
      logo={logo}
      formatMessage={formatMessage}
      onCollapse={handleMenuCollapse}
      onMenuHeaderClick={() => history.push('/')}
      // menuItemRender={(menuItemProps, defaultDom) => {
      //   if (menuItemProps.isUrl || !menuItemProps.path) {
      //     return defaultDom;
      //   }
      //   return <Link to={menuItemProps.path}>{defaultDom}</Link>;
      // }}
      // breadcrumbRender={(routers = []) => [
      //   {
      //     path: '/',
      //     breadcrumbName: formatMessage({ id: 'menu.home' }),
      //   },
      //   ...routers,
      // ]}
      // itemRender={(route, params, routes, paths) => {
      //   const first = routes.indexOf(route) === 0;
      //   return first ? (
      //     <Link to={paths.join('/')}>{route.breadcrumbName}</Link>
      //   ) : (
      //     <span>{route.breadcrumbName}</span>
      //   );
      // }}
      // footerRender={() => defaultFooterDom}
      menuDataRender={menuDataRender}
      rightContentRender={() => <RightContent />}
      {...props}
      {...settings}
    >
      <>
        <Menu className="topMenu">{renderTopMenu()}</Menu>
        {childrens.length > 0 && (
          <Sider
            className="sideMenu ant-pro-sider-fixed ant-pro-sider-light site-layout-background"
            onCollapse={() => handleMenuCollapse(!collapsed)}
            width={240}
            collapsedWidth={64}
            collapsed={collapsed}
            breakpoint="xl"
          >
            <div className="fold" onClick={() => handleMenuCollapse(!collapsed)}>
                {!collapsed ? <MenuFoldOutlined /> : <MenuUnfoldOutlined />}
              </div>
            <Menu
              mode="inline"
              style={{ width: !collapsed ? 240 : 80 }}
              inlineCollapsed={collapsed}
            >
              {renderSideMenu()}
            </Menu>
          </Sider>
        )}
        <div
          className="main"
          style={{ width: '100vw', paddingLeft: childrens.length > 0 ? collapsed ? 88 : 264 : 24, background: '#fff' }}
        >
          <Breadcrumb
            routes={urlToList(location.pathname)}
            itemRender={(route: any) => {
              const crumbName = route.replace(/\//g, '.');
              return <Breadcrumb.Item key={route}>{formatMessage({ id: `menu${crumbName}` })}</Breadcrumb.Item>;
            }}
          />
          <Authorized authority={authorized!.authority} noMatch={noMatch}>
            {children}
          </Authorized>
        </div>
      </>
    </ProLayout>
  );
};

export default connect(({ global, settings }: ConnectState) => ({
  collapsed: global.collapsed,
  settings,
}))(BasicLayout);
